home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 2 / AACD 2.iso / AACD / Online / Socks5 / src / server / s2s.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-03-10  |  4.8 KB  |  119 lines

  1. /* Copyright (c) 1995-1999 NEC USA, Inc.  All rights reserved.               */
  2. /*                                                                           */
  3. /* The redistribution, use and modification in source or binary forms of     */
  4. /* this software is subject to the conditions set forth in the copyright     */
  5. /* document ("Copyright") included with this distribution.                   */
  6.  
  7. /*
  8.  * $Id: s2s.c,v 1.24.4.4 1999/02/23 16:42:12 wlu Exp $
  9.  */
  10.  
  11. #include "socks5p.h"
  12. #include "daemon.h"
  13. #include "protocol.h"
  14. #include "validate.h"
  15. #include "sident.h"
  16. #include "info.h"
  17. #include "log.h"
  18.  
  19. /* Not sure when/if this is ever necessary during failed connects...         */
  20. static int Reset(S5IOInfo *info, int otype) {
  21.     S5IOHandle nfd;
  22.  
  23.     if ((nfd = socket(AF_INET, otype, 0)) == S5InvalidIOHandle) return -1;
  24.  
  25.     CLOSESOCKET(info->fd);
  26.     info->fd = nfd;
  27.     return 0;
  28. }
  29.  
  30. int S5SExchangeProtocol(S5IOInfo *iiop, S5IOInfo *oiop, S5LinkInfo *pri, char *ibuf, S5NetAddr *dest, S5NetAddr *resp) {
  31.     int i, rval = -1, optval = 1, optlen = sizeof(int);
  32.     S5NetAddr route;
  33.     u_char errbyte = 0; 
  34.     char effuser[S5_USERNAME_SIZE];
  35.     
  36.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10),     0, "S2S Using proxy (version %d) %s:%d", pri->nextVersion, ADDRANDPORT(&pri->sckAddr));
  37.  
  38.     if (!pri->nextVersion || !pri->nAltSckAddrs) {
  39.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "S2S: No proxy to connect to.");
  40.     return 0;
  41.     }
  42.  
  43.     GetRoute(&pri->sckAddr, pri->sckName, "tcp", &route);
  44.  
  45.     if (bind(oiop->fd, &route.sa, lsAddrSize(&route)) == 0) {
  46.         rval = connect(oiop->fd, &pri->sckAddr.sa, lsAddrSize(&pri->sckAddr));
  47.     }
  48.  
  49.     if (rval < 0 && pri->peerCommand == SOCKS_UDP) { /* multiple server is not supported yet */
  50.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING,   0, "S2S: Failed to connected to proxy at %s:%d", ADDRANDPORT(&pri->sckAddr));
  51.     goto error;
  52.     } else if (rval < 0) {
  53.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING,   0, "S2S: Failed to connected to proxy at %s:%d", ADDRANDPORT(&pri->sckAddr));
  54.  
  55.         getsockopt(oiop->fd, SOL_SOCKET, SO_TYPE, (char *)&optval, &optlen);
  56.  
  57.         for (i = 1; i < pri->nAltSckAddrs; i++) {
  58.         if (Reset(oiop, optval) < 0) goto error;
  59.  
  60.             lsAddrCopy(&pri->sckAddr, &pri->altSckAddrs[i], lsAddrSize(&pri->altSckAddrs[i]));
  61.             GetName(pri->sckName, &pri->sckAddr);
  62.         GetRoute(&pri->sckAddr, pri->sckName, "tcp", &route);
  63.  
  64.         if (bind(oiop->fd, &route.sa, lsAddrSize(&route)) < 0) goto error;
  65.  
  66.         if (connect(oiop->fd, &pri->altSckAddrs[i].sa, lsAddrSize(&pri->altSckAddrs[i])) == 0) break;
  67.         S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING,   0, "S2S: Failed to connected to proxy at %s:%d", ADDRANDPORT(&pri->altSckAddrs[i]));
  68.         }
  69.  
  70.         if (i == pri->nAltSckAddrs) goto error;
  71.     }
  72.  
  73.     if (ibuf) MakeIdentEntry(iiop->fd, oiop->fd, pri, ibuf);
  74.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10),     0, "S2S Connected to proxy %s:%d", ADDRANDPORT(&pri->sckAddr));
  75.  
  76.     MUTEX_LOCK(gpw_mutex);
  77.     strcpy(effuser, lsEffUser());
  78.     MUTEX_UNLOCK(gpw_mutex);
  79.  
  80.     if (lsProtoExchg(oiop->fd, oiop, dest, effuser, pri->nextVersion, pri->peerCommand, pri->peerReserved) < 0) {
  81.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING,   0, "S2S Protocol exchange with proxy (%s:%d) failed", ADDRANDPORT(&pri->sckAddr));
  82.     goto error;
  83.     }
  84.     
  85.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10),     0, "S2S Sent message to proxy (dest %s:%d)", ADDRANDPORT(dest));
  86.  
  87.     if (lsReadResponse(oiop->fd, oiop, resp, pri->nextVersion, &errbyte, &pri->nextReserved) < 0) {
  88.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING,   0, "S2S Recieved bad reply (%d) from proxy (%s:%d)", (int)errbyte, ADDRANDPORT(&pri->sckAddr));
  89.     goto error;
  90.     }
  91.     
  92.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10),     0, "S2S Received good reply from proxy");
  93.  
  94.     /* socks4 often put 0's in the reply's address field so we have to replace them with our */
  95.     /* best guess...                                                                         */
  96.     if (resp->sa.sa_family == AF_INET && (resp->sin.sin_addr.s_addr == INADDR_ANY || resp->sin.sin_addr.s_addr == htonl(INADDR_LOOPBACK))) {
  97.         resp->sin.sin_addr.s_addr = pri->sckAddr.sin.sin_addr.s_addr;
  98.     }
  99.  
  100.     return 0;
  101.  
  102. error:
  103.     SETSOCKETERROR(ECONNREFUSED);
  104.     return -1;
  105. }
  106.  
  107. int S5SExchgUdpCmd(S5IOHandle io, S5IOInfo *info, S5LinkInfo *pri, u_char version, u_char cmd, u_char *err) {
  108.     u_char flags;
  109.  
  110.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10),     0, "S2S Exchange UDP command (%d) for address (%s:%d)", (int)cmd, ADDRANDPORT(&pri->dstAddr));
  111.  
  112.     if (lsSendRequest(io, info, &pri->dstAddr, version, cmd, 0, NULL) < 0) {
  113.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING,   0, "S2S Fail to send UDP command");
  114.      return -1;
  115.     }
  116.  
  117.     return lsReadResponse(io, info, &pri->intAddr, version, err, &flags);
  118. }
  119.